// *** ADDED BY HEADER FIXUP ***
#include <list>
#include <string>
#include <vector>
// *** END ***
#include "ComandosNegociosUser.h"
RetornoInfo ComandosNegociosUser::acessarContaBD(const Email& email)
{
    RetornoInfo info;
    ComandoLerNome      CMDLN(email);
    ComandoLerSenha     CMDLS(email);
    ComandoLerNiver     CMDLA(email);
    ComandoLerIdade     CMDLI(email);
    ComandoLerClearance CMDLC(email);

    try
    {
        CMDLN.executar();
        CMDLS.executar();
        CMDLA.executar();
        CMDLI.executar();
        CMDLC.executar();

        info.nome      = CMDLN.getResultado();
        info.senha     = CMDLS.getResultado();
        info.email     = email.getValor();
        info.niver     = CMDLA.getResultado();
        info.idade     = CMDLI.getResultado();
        info.clearance = CMDLC.getResultado();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return info;
}
RetornoInfo ComandosNegociosUser::executarMostraConta(const Email& email)
{
    RetornoInfo retorno;
    try
    {
        retorno = acessarContaBD(email);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return retorno;
}
vector<string> ComandosNegociosUser::retrievePendentes(const Email& recebido,const int& estado)
{
    vector<string> vpendentes;
    string spendente;
    list<ElementoResultado> lpendentes;
    ElementoResultado resultado;
    ComandoLerAmigoPendentes CMDLAP(recebido,convertString(estado));
    try
    {
        CMDLAP.executar();
        lpendentes = CMDLAP.getResultado();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    while(!lpendentes.empty())
    {
        resultado = lpendentes.back();
        lpendentes.pop_back();
        spendente = resultado.getValorColuna();
        vpendentes.push_back(spendente);
    }
    return vpendentes;
}
vector<string> ComandosNegociosUser::retrieveConfirmados_v1(const Email& enviado,const int& estado)
{
    vector<string> vconfirmados;
    string sconfirmado;
    list<ElementoResultado> lconfirmados;
    ElementoResultado resultado;
    ComandoLerAmigoConfirmados_v1 CMDLAC(enviado,convertString(estado));
    try
    {
        CMDLAC.executar();
        lconfirmados = CMDLAC.getResultado();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    while(!lconfirmados.empty())
    {
        resultado = lconfirmados.back();
        lconfirmados.pop_back();
        sconfirmado = resultado.getValorColuna();
        vconfirmados.push_back(sconfirmado);
    }
    return vconfirmados;
}
vector<string> ComandosNegociosUser::retrieveConfirmados_v2(const Email& recebido,const int& estado)
{
    vector<string> vconfirmados;
    string sconfirmado;
    list<ElementoResultado> lconfirmados;
    ElementoResultado resultado;
    ComandoLerAmigoConfirmados_v2 CMDLAC(recebido,convertString(estado));
    try
    {
        CMDLAC.executar();
        lconfirmados = CMDLAC.getResultado();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    while(!lconfirmados.empty())
    {
        resultado = lconfirmados.back();
        lconfirmados.pop_back();
        sconfirmado = resultado.getValorColuna();
        vconfirmados.push_back(sconfirmado);
    }
    return vconfirmados;
}
vector<Message> ComandosNegociosUser::retrieveMuralFromBD(const Email& email)
{
    vector<Message> mural;
    Message mensagem;
    list<ElementoResultado> Contents;
    list<ElementoResultado> Tempos;
    ElementoResultado resultado;
    string content;
    TempoSistema tempo;
    ComandoLerMensagemContentMural CMDLMCM(email);
    ComandoLerMensagemTempoMural CMDLMTM(email);
    try
    {
        CMDLMCM.executar();
        Contents = CMDLMCM.getResultado();
        CMDLMTM.executar();
        Tempos = CMDLMTM.getResultado();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    while(!Contents.empty())
    {
        resultado = Contents.back();
        Contents.pop_back();
        content = resultado.getValorColuna();
        resultado = Tempos.back();
        Tempos.pop_back();
        tempo.setValor(resultado.getValorColuna());
        mensagem.setContent(content);
        mensagem.setTempo(tempo);
        mural.push_back(mensagem);
    }
    return mural;
}
vector<Message> ComandosNegociosUser::retrieveChatFromBD(const Email& enviado,const Email& recebido)
{
    vector<Message> chat;
    Message msg;
    list<ElementoResultado> Contents;
    list<ElementoResultado> Tempos;
    ElementoResultado resultado;
    string content;
    TempoSistema tempo;
    ComandoLerMensagemContentChat CMDLMCC(enviado,recebido);
    ComandoLerMensagemTempoChat CMDLMTC(enviado,recebido);
    try
    {
        CMDLMCC.executar();
        Contents = CMDLMCC.getResultado();
        CMDLMTC.executar();
        Tempos = CMDLMTC.getResultado();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    while(!Contents.empty())
    {
        resultado = Contents.back();
        Contents.pop_back();
        content = resultado.getValorColuna();
        resultado = Tempos.back();
        tempo.setValor(resultado.getValorColuna());
        msg.setContent(content);
        msg.setTempo(tempo);
        chat.push_back(msg);
    }
    return chat;
}
void ComandosNegociosUser::updateInBD(const Conta& acc)
{
    ComandoAtualizarUser CMDAU(acc);
    try
    {
        CMDAU.executar();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::updateInBD(const Email& enviado,const Email& recebido,const string& estado)
{
    ComandoAtualizarAmigo CMDAA(enviado,recebido,estado);
    try
    {
        CMDAA.executar();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::deleteFromBD(const Email& mail)
{
    ComandoRemoverUser CMDRU(mail);
    ComandoRemoverAmigoEnviado CMDRAE(mail);
    ComandoRemoverAmigoRecebido CMDRAR(mail);
    try
    {
        CMDRU.executar();
    }
    catch(EErroPersistencia& exp)
    {
        throw exp;
    }
    try
    {
        CMDRAE.executar();
    }
    catch(EErroPersistencia& exp)
    {
        throw exp;
    }
    try
    {
        CMDRAR.executar();
    }
    catch(EErroPersistencia& exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::insertInBD(const Conta& acc)
{
    ComandoCadastrarUser CMDCU(acc);
    try
    {
        CMDCU.executar();
    }
    catch(EErroPersistencia& exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::insertInBD(Message& msg)
{
    ComandoCadastrarMensagem CMDCM(msg);
    try
    {
        CMDCM.executar();
    }
    catch(EErroPersistencia& exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::insertInBD(Amigo& frnd)
{
    ComandoCadastrarAmigo CMDCA(frnd);
    try
    {
        CMDCA.executar();
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::executarRemocao(const Email& email)
{
    try
    {
        deleteFromBD(email);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::executarUpdate(const Nome& nome,const Idade& idade,const Data& data,const Email& email,const Senha& senha,const Clearance& level)
{
    Conta acc;
    acc = newConta(nome,idade,data,email,senha,level);
    try
    {
        updateInBD(acc);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::executarUpdate(const Email& enviado,const Email& recebido,const string& estado)
{
    try
    {
        updateInBD(enviado,recebido,estado);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::executarRegistro(const Nome& nome,const Idade& idade,const Data& data,const Email& email,const Senha& senha,const Clearance& level)
{
    Conta acc;
    acc = newConta(nome,idade,data,email,senha,level);
    try
    {
        insertInBD(acc);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
vector<Message> ComandosNegociosUser::executarMural(const Email& email)
{
    vector<Message> mural;
    try
    {
        mural = retrieveMuralFromBD(email);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return mural;
}
vector<Message> ComandosNegociosUser::executarChat(const Email& enviado,const Email& recebido)
{
    vector<Message> chat;
    try
    {
        chat = retrieveChatFromBD(enviado,recebido);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return chat;
}
void ComandosNegociosUser::executarCadastroMensagem(Message& msg)
{
    try
    {
        insertInBD(msg);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
void ComandosNegociosUser::executarCadastroAmigo(Amigo& frnd)
{
    try
    {
        insertInBD(frnd);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
}
vector<string> ComandosNegociosUser::executarConfirmados_v1(const Email& enviado,const int& estado)
{
    vector<string> confirmados;
    try
    {
        confirmados = retrieveConfirmados_v1(enviado,estado);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return confirmados;
}
vector<string> ComandosNegociosUser::executarConfirmados_v2(const Email& recebido,const int& estado)
{
    vector<string> confirmados;
    try
    {
        confirmados = retrieveConfirmados_v2(recebido,estado);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return confirmados;
}
vector<string> ComandosNegociosUser::executarPendentes(const Email& recebido,const int& estado)
{
    vector<string> pendentes;
    try
    {
        pendentes = retrievePendentes(recebido,estado);
    }
    catch(EErroPersistencia &exp)
    {
        throw exp;
    }
    return pendentes;
}
Conta ComandosNegociosUser::newConta(const Nome& nome,const Idade& idade,const Data& data,const Email& email,const Senha& senha,const Clearance& level)
{
    Conta acc(nome,idade,data,email,senha,level);
    return acc;
}
